﻿using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.Unity;
using MiniStock.BusinessLogic.EventProcessor;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using MiniStock.BusinessLogic.EventProcessor.EntityCache;
using MiniStock.BusinessLogic.EventProcessor.EventRepository;
using MiniStock.BusinessLogic.EventQueue.Queue;
using MiniStock.Entities;
using MiniStock.Entities.Common;
using MiniStock.Entities.Common.Events;
using MiniStock.Entities.Stock;
using MiniStock.Entities.Stock.Events;
using MiniStock.Entities.Stock.Events.Customer;
using MiniStock.Infrastructure;
using MiniStock.Infrastructure.Implementation;
using MiniStock.Infrastructure.Queue;

namespace MiniStock.BusinessLogic.EventProcessor.Test
{
    
    
    /// <summary>
    ///This is a test class for CustomerEventProcessorTest and is intended
    ///to contain all CustomerEventProcessorTest Unit Tests
    ///</summary>
    [TestClass()]
    public class InitMessageTest
    {

        public static IUnityContainer RootContainer;

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext)
        {
        }
        
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        [TestInitialize()]
        public void MyTestInitialize()
        {
            RootContainer = new UnityContainer();
            RootContainer.RegisterType<IEventQueue, MemoryQueue>(new ContainerControlledLifetimeManager());
            RootContainer.RegisterType<IEventQueue, MemoryQueue>("OutputQueue", new ContainerControlledLifetimeManager());
            RootContainer.RegisterType<IRepository<EventProcessorEventData>, EventDbRepository>(new ContainerControlledLifetimeManager());
        }

        //Use TestCleanup to run code after each test has run
        [TestCleanup()]
        public void MyTestCleanup()
        {
            var db = new EventDbContext();
            db.Database.ExecuteSqlCommand("delete from Events");
        }

        //
        #endregion

        public Guid[] CustomerIdList = new[]{
                                               Guid.NewGuid(),
                                               Guid.NewGuid(),
                                           };
        /// <summary>
        ///A test for CustomerEventProcessor Constructor
        ///</summary>
        public void CustomerEventProcessor_Test_SetName()
        {
            EventProcessorWorker sut = RootContainer.Resolve<EventProcessorWorker>();
            IEventQueue outputQueue = RootContainer.Resolve<IEventQueue>("OutputQueue");
            var customerId = CustomerIdList[0];
            EntityBase customer;

            sut.AddEvent(new CreateCustomerEvent
            {
                EventId = Guid.NewGuid(),
                EventDate = DateTime.Now.AddSeconds(-1),
                Id = customerId,
                Name = "Teszt Pista",
                //SubmittedBy = Guid.NewGuid().ToString(),
            });

            Assert.IsFalse(sut.EntityCache.TryGetItemByHash("Customer|" + customerId.ToString(), out customer));
            var result = sut.DoWork();
            Assert.AreEqual(true, result);
            Assert.IsFalse(sut.EntityCache.TryGetItemByHash("Customer|" + customerId.ToString(), out customer));
            Assert.IsNull(customer);

            sut.AddEvent(new InitWorker
            {
                Initializers = new List<string>
                                 {
                                     typeof(PluginEntryPoint).AssemblyQualifiedName
                                 },
            });

            sut.AddEvent(new CreateCustomerEvent
            {
                EventId = Guid.NewGuid(),
                EventDate = DateTime.Now.AddSeconds(-1),
                Id = customerId,
                Name = "Teszt Pista",
                //SubmittedBy = Guid.NewGuid().ToString(),
            });

            Assert.IsFalse(sut.EntityCache.TryGetItemByHash("Customer|" + customerId.ToString(), out customer));
            result = sut.DoWork();
            Assert.AreEqual(true, result);
            result = sut.DoWork();
            Assert.AreEqual(true, result);
            Assert.IsTrue(sut.EntityCache.TryGetItemByHash("Customer|" + customerId.ToString(), out customer));
            Assert.IsNotNull(customer);
            Assert.AreEqual("Teszt Pista", ((Customer)customer).Name);
            var events = sut.EntityCache.Repository.ToList();
            Assert.AreEqual(2, events.Count());

            //var outEvents = outputQueue.CollectEvents(DateTime.MinValue);
            //Assert.AreEqual(1, outEvents.Count);
        }
    }
}
